package org.foreningsgatan.mercenaries.manual.generator;

import java.util.Random;

import org.foreningsgatan.modular.terrain.model.SimpleMap;

/**
 * 
 * Copyright (c) 2008 Joakim Back
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 * @author Joakim Back
 *
 */
public class InterpolatedMapGenerator {
	static private int COORD_X = 0;
	static private int COORD_Y = 1;
	static private float MAX_DISTANCE = 0.15f;
	static private int NUM_OF_PEAKS = 30;
	
	class Peak {
		protected int x;
		protected int y;
		
		public Peak(int pX, int pY) {
			this.x = pX;
			this.y = pY;
		}
	}
	
	private static int[][] generatePeaks(int pSize, int pTotals) {
		Random vRandom = new Random();
		
		int[][] vArray = new int[pTotals][2];
		
		for (int i = 0; i < pTotals; i++) {
			vArray[i][COORD_X] = vRandom.nextInt(pSize);
			vArray[i][COORD_Y] = vRandom.nextInt(pSize);
		}
		
		return vArray;
	}
	
	private static double getDistanceFactor(int x, int y, int[][] pPeaks, int pSize) {
		double vMinDistance = Double.MAX_VALUE;
		double vMaxDistance = (MAX_DISTANCE * pSize);
		
		for (int i = 0; i < pPeaks.length; i++) {
			int vDX = pPeaks[i][COORD_X] - x;
			int vDY = pPeaks[i][COORD_Y] - y;
			
			double vDistance = Math.sqrt(vDX * vDX + vDY * vDY);
			
			if (vDistance < vMinDistance) {
				vMinDistance = vDistance;
			}
		}
		
		if (vMinDistance < vMaxDistance) {
			return vMinDistance / vMaxDistance;
		} else {
			return 1.0;
		}
	}
	
	public static SimpleMap generate(int size, Object[] objects) {
		int[][] vPeaks = generatePeaks(size, NUM_OF_PEAKS);
		
		SimpleMap map = new SimpleMap(size);
		
		for (int y = 0; y < size; y++) {
			for (int x = 0; x < size; x++) {
				double vFactor = getDistanceFactor(x, y, vPeaks, size);
				int vIndex = (int) (vFactor * (objects.length - 1));
				
				map.set(x, y, objects[vIndex]);
			}
		}
		
		return map;
	}
}
